// =================================================================================================
//
//	CopyEngine Framework
//	Copyright 2012 Eran. All Rights Reserved.
//
//	This program is free software. You can redistribute and/or modify it
//	in accordance with the terms of the accompanying license agreement.
//
// =================================================================================================

package copyengine.utils.math.dropEffect
{
    public class CEDropItemEffectTweenUpdateProxyObject
    {
        //所有抛物线数值
        private var mAllSubParabolaDataVector:Vector.<CEDropItemEffectTweenUpdateSubParabolaData>;

        //最终运动时候X轴停的坐标
        private var mEndOffsetX:int;

        private var mCurrentTweenX:Number;

        private var mTarget:*;
        private var mTargetDefaultX:int;
        private var mTargetDefaultY:int;

        public function CEDropItemEffectTweenUpdateProxyObject()
        {
        }

        //==================================
        //== Initialize & Dispose
        //==================================

        public function initialize(_startMX:int,
                                   _startMY:int,
                                   _decayMX:Number = 0.3,
                                   _decayMY:Number = 0.4,
                                   _decayTime:int = 3):void
        {
            mCurrentTweenX = 0;
            var currentMX:int = _startMX;
            var currentMY:int = _startMY;
            var currentOffsetX:int = 0;
            mAllSubParabolaDataVector = new Vector.<CEDropItemEffectTweenUpdateSubParabolaData>();
            for (var i:int = 0; i < _decayTime; i++)
            {
                var data:CEDropItemEffectTweenUpdateSubParabolaData = new CEDropItemEffectTweenUpdateSubParabolaData();
                data.M_X = currentMX;
                data.M_Y = currentMY;
                data.START_X = currentOffsetX;
                data.A = -data.M_Y / (data.M_X * data.M_X);
                data.B = 2 * data.M_Y / data.M_X;
                data.END_X = data.M_X * 2;
                mAllSubParabolaDataVector.push(data);

                currentOffsetX += currentMX * 2;
                currentMX = currentMX * (1 - _decayMX);
                currentMY = currentMY * (1 - _decayMY);
            }
            mEndOffsetX = currentOffsetX;
        }

        public function dispose():void
        {
            mAllSubParabolaDataVector.length = 0;
            mAllSubParabolaDataVector = null;
        }

        //==================================
        //== Public Function
        //==================================

        public function setTarget(_target:*):void
        {
            mTarget = _target;
            mTargetDefaultX = mTarget["x"];
            mTargetDefaultY = mTarget["y"];
        }

        public function set x(_tweenX:Number):void
        {
            mCurrentTweenX = _tweenX;
            updateTarget();
        }

        public function get x():Number {return mCurrentTweenX;}

        /**
         * DropItemEffect播放结束后的X值和起始X值之间的偏移量
         */
        public function get endOffsetX():int
        {return mEndOffsetX;}


        /**
         * 如果传入了Target对象则可以完全由Proxy类代理掉Target的移动
         * 如果上层逻辑不传入Target对象,则需要手动调用该函数获取对应的y值坐标
         *
         * @param _x            注意!!这里的X值坐标不是Target真正的X坐标,小球掉落动画的X坐标范围是(0,mEndOffsetX). 该X坐标
         *                      指的是在这个范围内的x坐标值, 真实的Target坐标为: mTargetDefaultX + 该X坐标值
         * @return
         */
        public function getDropItemEffectYByDropItemEffectX(_x:Number):Number
        {
            var subParabolaData:CEDropItemEffectTweenUpdateSubParabolaData = getSubParabolaDataByX(_x);
            var x:Number = _x - subParabolaData.START_X;
            if (subParabolaData != null)
            {
                return x >= 0 ? -(subParabolaData.A * x * x + subParabolaData.B * x) : subParabolaData.A * x * x + subParabolaData.B * x;
            }
            else
            {
                return 0;
            }
        }

        //==================================
        //== Private Function
        //==================================

        private function updateTarget():void
        {
            mTarget["x"] = mTargetDefaultX + mCurrentTweenX;
            mTarget["y"] = mTargetDefaultY + getDropItemEffectYByDropItemEffectX(mCurrentTweenX);
        }

        private function getSubParabolaDataByX(_x:Number):CEDropItemEffectTweenUpdateSubParabolaData
        {
            var length:int = mAllSubParabolaDataVector.length;
            for (var i:int = 0; i < length; i++)
            {
                var data:CEDropItemEffectTweenUpdateSubParabolaData = mAllSubParabolaDataVector[i];
                if (Math.abs(data.START_X + data.END_X) >= Math.abs(_x))
                {
                    return data;
                }
            }
            return null;
        }

    }
}
